<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <h3>汨逸 消息：<span id="msg_num">0</span></h3>

    <ul id="msg">

    </ul>

    <textarea id="user_input"></textarea>
    <button id="user_submit">提交</button>
    <script>
    var Observer = (function() {
        // 防止消息队列爆满而篡改，故将消息容器作为静态私有变量保存
        var _message = {};
        return {
            // 注册信息接口
            regist: function(type, fn) {
                // 如果此消息不存在，则应该创建一个消息类型
                if (typeof _message[type] === 'undefined') {
                    // 将动作推入到该消息对应的动作执行队列中
                    _message[type] = [fn];
                } else {
                    // 如果此消息存在,将动作方法推入该消息对应的动作执行序列中
                    _message[type].push(fn);
                }
            },
            // 发布信息接口
            fire: function(type, args) {
                // 如果该消息没有被注册，则返回
                if (!_message[type]) {
                    return;
                }
                // 定义消息信息
                var events = {
                        type: type, // 消息类型
                        args: args || {} // 消息携带数据
                    },
                    i = 0,
                    len = _message[type].length; // 消息动作长度
                // 遍历消息动作
                for (; i < len; i++) {
                    _message[type][i].call(this, events);
                }
            },
            // 移出信息接口
            remove: function(type, fn) {
                // 如果消息队列存在
                if (_message[type] instanceof Array) {
                    // 从最后一个消息动作遍历
                    var i = _message[type].length - 1;
                    for (; i >= 0; i--) {
                        // 如果存在该动作则在消息动作序列中移除相应动作
                        _message[type][i] === fn && _message[type].splice(i, 1);
                    }
                }
            }
        }
    })()
    /*
		发布留言与删除留言，用户主动触发=》观察者发布消息
		评论的追加以及用户消息数量的增减，被动触发=》订阅者注册消息
		用户信息模块既是信息的接收者，也是模块的发送者
			提交模块：发送者
			浏览器模块：接收者
    */
    // 外观模式简化获取元素
    function $(id) {
        return document.getElementById(id);
    }
    // 工程师A - 增加用户消息=》发布 和按钮移除消息=》删除
    (function() {
        // 评论的增加
        function addMsgItem(e) {
            var text = e.args.text,
                ul = $('msg'),
                li = document.createElement('li'),
                span = document.createElement('span');
            li.innerHTML = text;
            span.innerHTML = 'X';
            li.appendChild(span);
            ul.appendChild(li);
            // 关闭按钮
            span.onclick = function() {
                // 移除留言
                ul.removeChild(li);
                // 发布删除留言消息
                Observer.fire('removeCommentMessage', {
                    num: -1
                });
            }
        }
        // 注册添加评论信息
        Observer.regist('addCommentMessage', addMsgItem);
    })();
    // 更改用户消息数量
    (function() {
        // 更改用户消息数目
        function changeMsgNum(e) {
            // 获取需要增加的用户消息数目
            var num = e.args.num;
            console.log($('msg_num'.innerHTML));
            // 增加用户消息数目并写入页面中
            $('msg_num').innerHTML = parseInt($('msg_num').innerHTML) + num;
        }
        // 注册添加评论信息
        Observer.regist('addCommentMessage', changeMsgNum);
        Observer.regist('removeCommentMessage', changeMsgNum);
    })();
    // 提交信息时,触发发布消息
    (function() {
        // 用户点击提交按钮
        $('user_submit').onclick = function() {
            // 获取用户输入框中输入的信息
            var text = $('user_input');
            // 如果消息为空则提交失败
            if (text.value === '') {
                return;
            }
            // 发布-则评论消息
            Observer.fire('addCommentMessage', {
                text: text.value,
                num: 1
            });
            text.value = '';
        }
    })();
    </script>
</body>

</html>